<!DOCTYPE HTML>
<html lang="zh-CN">


<head>
    <meta charset="utf-8">
    <meta name="keywords" content="TypeScript">
    <meta name="description" content="TypeScript">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="renderer" content="webkit|ie-stand|ie-comp">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <meta name="referrer" content="no-referrer-when-downgrade">
    <!-- Global site tag (gtag.js) - Google Analytics -->


    <title>TypeScript | B-612</title>
    <link rel="icon" type="image/png" href="/favicon.png">
    


    <!-- bg-cover style     -->



<link rel="stylesheet" type="text/css" href="/libs/awesome/css/all.min.css">
<link rel="stylesheet" type="text/css" href="/libs/materialize/materialize.min.css">
<link rel="stylesheet" type="text/css" href="/libs/aos/aos.css">
<link rel="stylesheet" type="text/css" href="/libs/animate/animate.min.css">
<link rel="stylesheet" type="text/css" href="/libs/lightGallery/css/lightgallery.min.css">
<link rel="stylesheet" type="text/css" href="/css/matery.css">
<link rel="stylesheet" type="text/css" href="/css/my.css">
<link rel="stylesheet" type="text/css" href="/css/dark.css" media="none" onload="if(media!='all')media='all'">




    <link rel="stylesheet" href="/libs/tocbot/tocbot.css">
    <link rel="stylesheet" href="/css/post.css">




    
        <link rel="stylesheet" type="text/css" href="/css/reward.css">
    



    <script src="/libs/jquery/jquery-3.6.0.min.js"></script>

<meta name="generator" content="Hexo 6.3.0">
<style>.github-emoji { position: relative; display: inline-block; width: 1.2em; min-height: 1.2em; overflow: hidden; vertical-align: top; color: transparent; }  .github-emoji > span { position: relative; z-index: 10; }  .github-emoji img, .github-emoji .fancybox { margin: 0 !important; padding: 0 !important; border: none !important; outline: none !important; text-decoration: none !important; user-select: none !important; cursor: auto !important; }  .github-emoji img { height: 1.2em !important; width: 1.2em !important; position: absolute !important; left: 50% !important; top: 50% !important; transform: translate(-50%, -50%) !important; user-select: none !important; cursor: auto !important; } .github-emoji-fallback { color: inherit; } .github-emoji-fallback img { opacity: 0 !important; }</style>
<link rel="alternate" href="/atom.xml" title="B-612" type="application/atom+xml">
</head>


<body>
    <header class="navbar-fixed">
    <nav id="headNav" class="bg-color nav-transparent">
        <div id="navContainer" class="nav-wrapper container">
            <div class="brand-logo">
                <a href="/" class="waves-effect waves-light">
                    
                    <img src="/medias/logo.png" class="logo-img" alt="LOGO">
                    
                    <span class="logo-span">B-612</span>
                </a>
            </div>
            

<a href="#" data-target="mobile-nav" class="sidenav-trigger button-collapse"><i class="fas fa-bars"></i></a>
<ul class="right nav-menu">
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/" class="waves-effect waves-light">
      
      <i class="fas fa-home" style="zoom: 0.6;"></i>
      
      <span>首页</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/tags" class="waves-effect waves-light">
      
      <i class="fas fa-tags" style="zoom: 0.6;"></i>
      
      <span>标签</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/categories" class="waves-effect waves-light">
      
      <i class="fas fa-bookmark" style="zoom: 0.6;"></i>
      
      <span>分类</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/archives" class="waves-effect waves-light">
      
      <i class="fas fa-archive" style="zoom: 0.6;"></i>
      
      <span>归档</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/tips" class="waves-effect waves-light">
      
      <i class="fa-solid fa-wand-magic-sparkles" style="zoom: 0.6;"></i>
      
      <span>附录</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/about" class="waves-effect waves-light">
      
      <i class="fas fa-user-circle" style="zoom: 0.6;"></i>
      
      <span>关于</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/friends" class="waves-effect waves-light">
      
      <i class="fas fa-address-book" style="zoom: 0.6;"></i>
      
      <span>友情链接</span>
    </a>
    
  </li>
  
  <li>
    <a href="#searchModal" class="modal-trigger waves-effect waves-light">
      <i id="searchIcon" class="fas fa-search" title="搜索" style="zoom: 0.85;"></i>
    </a>
  </li>
  <li>
    <a href="javascript:;" class="waves-effect waves-light" onclick="switchNightMode()" title="深色/浅色模式" >
      <i id="sum-moon-icon" class="fas fa-sun" style="zoom: 0.85;"></i>
    </a>
  </li>
</ul>


<div id="mobile-nav" class="side-nav sidenav">

    <div class="mobile-head bg-color">
        
        <img src="/medias/logo.png" class="logo-img circle responsive-img">
        
        <div class="logo-name">B-612</div>
        <div class="logo-desc">
            
            Never really desperate, only the lost of the soul.
            
        </div>
    </div>

    <ul class="menu-list mobile-menu-list">
        
        <li class="m-nav-item">
	  
		<a href="/" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-home"></i>
			
			首页
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/tags" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-tags"></i>
			
			标签
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/categories" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-bookmark"></i>
			
			分类
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/archives" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-archive"></i>
			
			归档
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/tips" class="waves-effect waves-light">
			
			    <i class="fa-fw fa-solid fa-wand-magic-sparkles"></i>
			
			附录
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/about" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-user-circle"></i>
			
			关于
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/friends" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-address-book"></i>
			
			友情链接
		</a>
          
        </li>
        
        
        <li><div class="divider"></div></li>
        <li>
            <a href="https://github.com/wangjueya/B612-Factory" class="waves-effect waves-light" target="_blank">
                <i class="fab fa-github-square fa-fw"></i>Fork Me
            </a>
        </li>
        
    </ul>
</div>


        </div>

        
            <style>
    .nav-transparent .github-corner {
        display: none !important;
    }

    .github-corner {
        position: absolute;
        z-index: 10;
        top: 0;
        right: 0;
        border: 0;
        transform: scale(1.1);
    }

    .github-corner svg {
        color: #0f9d58;
        fill: #fff;
        height: 64px;
        width: 64px;
    }

    .github-corner:hover .octo-arm {
        animation: a 0.56s ease-in-out;
    }

    .github-corner .octo-arm {
        animation: none;
    }

    @keyframes a {
        0%,
        to {
            transform: rotate(0);
        }
        20%,
        60% {
            transform: rotate(-25deg);
        }
        40%,
        80% {
            transform: rotate(10deg);
        }
    }
</style>

<a href="https://github.com/wangjueya/B612-Factory" class="github-corner tooltipped hide-on-med-and-down" target="_blank"
   data-tooltip="Fork Me" data-position="left" data-delay="50">
    <svg viewBox="0 0 250 250" aria-hidden="true">
        <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
        <path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
              fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
        <path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
              fill="currentColor" class="octo-body"></path>
    </svg>
</a>
        
    </nav>

</header>

    



<div class="bg-cover pd-header post-cover" style="background-image: url('/medias/featureimages/5.jpg')">
    <div class="container" style="right: 0px;left: 0px;">
        <div class="row">
            <div class="col s12 m12 l12">
                <div class="brand">
                    <h1 class="description center-align post-title">TypeScript</h1>
                </div>
            </div>
        </div>
    </div>
</div>




<main class="post-container content">

    
    <div class="row">
    <div id="main-content" class="col s12 m12 l9">
        <!-- 文章内容详情 -->
<div id="artDetail">
    <div class="card">
        <div class="card-content article-info">
            <div class="row tag-cate">
                <div class="col s7">
                    
                    <div class="article-tag">
                        
                            <a href="/tags/TypeScript/">
                                <span class="chip bg-color">TypeScript</span>
                            </a>
                        
                    </div>
                    
                </div>
                <div class="col s5 right-align">
                    
                    <div class="post-cate">
                        <i class="fas fa-bookmark fa-fw icon-category"></i>
                        
                            <a href="/categories/04-Programming-Languages/" class="post-category">
                                04-Programming-Languages
                            </a>
                        
                            <a href="/categories/04-Programming-Languages/JavaScript/" class="post-category">
                                JavaScript
                            </a>
                        
                    </div>
                    
                </div>
            </div>

            <div class="post-info">
                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-minus fa-fw"></i>发布日期:&nbsp;&nbsp;
                    2022-10-18
                </div>
                

                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-check fa-fw"></i>更新日期:&nbsp;&nbsp;
                    2022-11-14
                </div>
                

                
                <div class="info-break-policy">
                    <i class="far fa-file-word fa-fw"></i>文章字数:&nbsp;&nbsp;
                    2.2k
                </div>
                

                
                <div class="info-break-policy">
                    <i class="far fa-clock fa-fw"></i>阅读时长:&nbsp;&nbsp;
                    10 分
                </div>
                

                
                    <div id="busuanzi_container_page_pv" class="info-break-policy">
                        <i class="far fa-eye fa-fw"></i>阅读次数:&nbsp;&nbsp;
                        <span id="busuanzi_value_page_pv"></span>
                    </div>
				

                
                <div class="info-break-policy" style='margin-left: 3px'>
                    
                    <a target="_blank" rel="noopener" href="https://github.com/WANGJUEYA/magic-book/edit/master/04-Programming-Languages/JavaScript/TypeScript.md">
                        <i class="far fa-regular fa-pen-to-square"></i>
                    </a>
                </div>
                
            </div>
        </div>
        <hr class="clearfix">

        
        <!-- 是否加载使用自带的 prismjs. -->
        <link rel="stylesheet" href="/libs/prism/prism.min.css">
        

        

        <div class="card-content article-card-content">
            <div id="articleContent">
                <p>官方文档 <a target="_blank" rel="noopener" href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#object-types">https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#object-types</a></p>
<p>在线运行 <a target="_blank" rel="noopener" href="https://www.typescriptlang.org/play">https://www.typescriptlang.org/play</a></p>
<p>学习手册1 <a target="_blank" rel="noopener" href="https://www.wenjiangs.com/doc/typescript-typeguard">https://www.wenjiangs.com/doc/typescript-typeguard</a></p>
<h2 id="语法介绍">语法介绍</h2>
<h3 id="基础介绍">基础介绍</h3>
<table>
<thead>
<tr>
<th style="text-align:center">关键字</th>
<th style="text-align:center">名称</th>
<th style="text-align:left">解释</th>
<th style="text-align:left">用例</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">boolean</td>
<td style="text-align:center">布尔值</td>
<td style="text-align:left">最基本的数据类型就是简单的值</td>
<td style="text-align:left">let isDone: boolean = false;</td>
</tr>
<tr>
<td style="text-align:center">number</td>
<td style="text-align:center">数字</td>
<td style="text-align:left">和JavaScript一样，TypeScript里的所有数字都是浮点数。<br>这些浮点数的类型是 number。<br>除了支持十进制和十六进制字面量，<br>TypeScript还支持ECMAScript 2015中引入的二进制和八进制字面量。</td>
<td style="text-align:left">let decLiteral: number = 6;<br>let hexLiteral: number = 0xf00d;<br>let binaryLiteral: number = 0b1010;<br>let octalLiteral: number = 0o744;</td>
</tr>
<tr>
<td style="text-align:center">string</td>
<td style="text-align:center">字符串</td>
<td style="text-align:left">我们使用 string表示文本数据类型。<br>和JavaScript一样，可以使用双引号（ "）或单引号（'）表示字符串。<br>还可以使用模板字符串<br>这种字符串是被反引号包围（ `），并且以${ expr }这种形式嵌入表达式。</td>
<td style="text-align:left">let myName: string = 'bob';<br>myName = 'smith';<br>let sentence: string = `Hello, my name is ${ myName }.`;<br>console.log(sentence);</td>
</tr>
<tr>
<td style="text-align:center">array</td>
<td style="text-align:center">数组</td>
<td style="text-align:left">有两种方式可以定义数组。<br>第一种，可以在元素类型后面接上 []，表示由此类型元素组成的一个数组<br>第二种方式是使用数组泛型，Array&lt;元素类型&gt;</td>
<td style="text-align:left">let myList1: number[] = [1, 2, 3];<br>console.log(myList1);<br>let myList2: Array&lt;number&gt; = [1, 2, 3];<br>console.log(myList2);</td>
</tr>
<tr>
<td style="text-align:center">Tuple</td>
<td style="text-align:center">元组</td>
<td style="text-align:left">元组类型允许表示一个已知元素数量和类型的数组，各元素的类型不必相同。<br>当访问一个已知索引的元素，会得到正确的类型<br>当访问一个越界的元素，会使用联合类型替代<br><a target="_blank" rel="noopener" href="https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types">扩展使用</a></td>
<td style="text-align:left">let x: [string, number];<br>let x: [boolean, …string, number];<br></td>
</tr>
<tr>
<td style="text-align:center">enum</td>
<td style="text-align:center">枚举</td>
<td style="text-align:left">使用枚举类型可以为一组数值赋予友好的名字。<br>使用枚举可以更简单的表明意图或创建一组特殊意义的集合<br>枚举支持数字类型和字符串类型<br><a target="_blank" rel="noopener" href="https://www.typescriptlang.org/docs/handbook/enums.html">扩展使用</a></td>
<td style="text-align:left">enum Color {RAD = ‘red’, BLUD = 0}<br>console.log(Color.RAD) // red<br>console.log(Color[0]) // BLUD</td>
</tr>
<tr>
<td style="text-align:center">any</td>
<td style="text-align:center">Any</td>
<td style="text-align:left">编程阶段还不清楚类型的变量指定一个类型</td>
<td style="text-align:left">let notSure: any = 4;<br>notSure = “maybe a string instead”;<br>notSure = false; // okay, definitely a boolean</td>
</tr>
<tr>
<td style="text-align:center">void<br>null<br>undefined</td>
<td style="text-align:center">Void<br>Null<br>Undefined</td>
<td style="text-align:left">void类型像是与any类型相反，它表示没有任何类型。<br>当一个函数没有返回值时，你通常会见到其返回值类型是 void.<br>声明一个void类型的变量没有什么大用，因为你只能为它赋予undefined和null.<br>undefined和null两者各自有自己的类型分别叫做undefined和null.<br>默认情况下null和undefined是所有类型的子类型.</td>
<td style="text-align:left">let unusable: void = undefined;<br>// Not much else we can assign to these variables!<br>let u: undefined = undefined;<br>let n: null = null;</td>
</tr>
<tr>
<td style="text-align:center">never</td>
<td style="text-align:center">Never</td>
<td style="text-align:left">never类型表示的是那些永不存在的值的类型<br>never类型是任何类型的子类型，也可以赋值给任何类型</td>
<td style="text-align:left">// 返回never的函数必须存在无法达到的终点<br>function error(message: string): never {<br>    throw new Error(message);<br>}</td>
</tr>
<tr>
<td style="text-align:center">object</td>
<td style="text-align:center">Object</td>
<td style="text-align:left">指任何带有属性的JavaScript值-非基础类型<br>对象类型也可以指定其部分或全部属性是可选的。</td>
<td style="text-align:left">function printName(obj: { first: string; last?: string }) {<br>  // …<br>}<br>// Both OK<br>printName({ first: “Bob” });<br>printName({ first: “Alice”, last: “Alisson” });</td>
</tr>
<tr>
<td style="text-align:center">type</td>
<td style="text-align:center">Type Aliases</td>
<td style="text-align:left">多次使用同一个类型并以一个名字来引用它是很常见的。</td>
<td style="text-align:left">type Point = {<br>  x: number;<br>  y: number;<br>};<br>// Exactly the same as the earlier example<br>function printCoord(pt: Point) {<br>  console.log("The coordinate’s x value is " + pt.x);<br>  console.log("The coordinate’s y value is " + pt.y);<br>}<br>printCoord({ x: 100, y: 100 });</td>
</tr>
<tr>
<td style="text-align:center">interface</td>
<td style="text-align:center">Interfaces</td>
<td style="text-align:left">接口声明是命名一个对象类型的另一种方式。</td>
<td style="text-align:left">interface Point {<br>  x: number;<br>  y: number;<br>}<br>function printCoord(pt: Point) {<br>  console.log("The coordinate’s x value is " + pt.x);<br>  console.log("The coordinate’s y value is " + pt.y);<br>}<br>printCoord({ x: 100, y: 100 });</td>
</tr>
<tr>
<td style="text-align:center">class</td>
<td style="text-align:center">Class</td>
<td style="text-align:left">TypeScript实现了 <code>class</code> 关键字 <br> <a target="_blank" rel="noopener" href="https://www.typescriptlang.org/docs/handbook/2/classes.html#class-members">扩展使用</a></td>
<td style="text-align:left"></td>
</tr>
</tbody>
</table>
<h4 id="元组使用详情">元组使用详情</h4>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">let</span> x<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">,</span> <span class="token builtin">number</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// Declare a tuple type</span>
<span class="token comment">// Initialize it</span>
x <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'hello'</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// OK</span>
<span class="token comment">// Initialize it incorrectly</span>
x <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token string">'hello'</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// Error</span>
<span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// OK</span>
<span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Error, 'number' does not have 'substr'</span>
x<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'world'</span><span class="token punctuation">;</span> <span class="token comment">// OK, 字符串可以赋值给(string | number)类型</span>
<span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// OK, 'string' 和 'number' 都有 toString</span>
x<span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token comment">// Error, 布尔不是(string | number)类型</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h5 id="元组的进阶使用">元组的进阶使用</h5>
<p>Tuples can also have rest elements, which have to be an array/tuple type.</p>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">type</span> <span class="token class-name">StringNumberBooleans</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">,</span> <span class="token builtin">number</span><span class="token punctuation">,</span> <span class="token operator">...</span><span class="token builtin">boolean</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">type</span> <span class="token class-name">StringBooleansNumber</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">,</span> <span class="token operator">...</span><span class="token builtin">boolean</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token builtin">number</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">type</span> <span class="token class-name">BooleansStringNumber</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span><span class="token builtin">boolean</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token builtin">string</span><span class="token punctuation">,</span> <span class="token builtin">number</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<ul>
<li><code>StringNumberBooleans</code> describes a tuple whose first two elements are <code>string</code> and <code>number</code> respectively, but which may have any number of <code>boolean</code>s following.</li>
<li><code>StringBooleansNumber</code> describes a tuple whose first element is <code>string</code> and then any number of <code>boolean</code>s and ending with a <code>number</code>.</li>
<li><code>BooleansStringNumber</code> describes a tuple whose starting elements are any number of <code>boolean</code>s and ending with a <code>string</code> then a <code>number</code>.</li>
</ul>
<p>A tuple with a rest element has no set “length” - it only has a set of well-known elements in different positions.</p>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">const</span> a<span class="token operator">:</span> StringNumberBooleans <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"hello"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> b<span class="token operator">:</span> StringNumberBooleans <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"beautiful"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> c<span class="token operator">:</span> StringNumberBooleans <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"world"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p>Why might optional and rest elements be useful? Well, it allows TypeScript to correspond tuples with parameter lists. Tuples types can be used in <a target="_blank" rel="noopener" href="https://www.typescriptlang.org/docs/handbook/2/functions.html#rest-parameters-and-arguments">rest parameters and arguments</a>, so that the following:</p>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">function</span> <span class="token function">readButtonInput</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">,</span> <span class="token builtin">number</span><span class="token punctuation">,</span> <span class="token operator">...</span><span class="token builtin">boolean</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>name<span class="token punctuation">,</span> version<span class="token punctuation">,</span> <span class="token operator">...</span>input<span class="token punctuation">]</span> <span class="token operator">=</span> args<span class="token punctuation">;</span>
  <span class="token comment">// ...</span>
<span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<p>is basically equivalent to:</p>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">function</span> <span class="token function">readButtonInput</span><span class="token punctuation">(</span>name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">,</span> version<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">,</span> <span class="token operator">...</span>input<span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// ...</span>
<span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p>This is handy when you want to take a variable number of arguments with a rest parameter, and you need a minimum number of elements, but you don’t want to introduce intermediate variables.</p>
<h4 id="枚举的使用详情">枚举的使用详情</h4>
<ul>
<li>
<p>The enum member is initialized with a constant enum expression. A constant enum expression is a subset of TypeScript expressions that can be fully evaluated at compile time. An expression is a constant enum expression if it is:</p>
<ol>
<li>a literal enum expression (basically a string literal or a numeric literal)</li>
<li>a reference to previously defined constant enum member (which can originate from a different enum)</li>
<li>a parenthesized constant enum expression</li>
<li>one of the <code>+</code>, <code>-</code>, <code>~</code> unary operators applied to constant enum expression</li>
<li><code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>, <code>%</code>, <code>&lt;&lt;</code>, <code>&gt;&gt;</code>, <code>&gt;&gt;&gt;</code>, <code>&amp;</code>, <code>|</code>, <code>^</code> binary operators with constant enum expressions as operands</li>
</ol>
<p>It is a compile time error for constant enum expressions to be evaluated to <code>NaN</code> or <code>Infinity</code>.</p>
</li>
</ul>
<p>In all other cases enum member is considered computed.</p>
<pre class="line-numbers language-none"><code class="language-none">enum FileAccess {
  // constant members
  None,
  Read = 1 &lt;&lt; 1,
  Write = 1 &lt;&lt; 2,
  ReadWrite = Read | Write,
  // computed member
  G = "123".length,
}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">enum</span> LogLevel <span class="token punctuation">{</span>
    <span class="token constant">ERROR</span><span class="token punctuation">,</span>
    <span class="token constant">WARN</span><span class="token punctuation">,</span>
    <span class="token constant">INFO</span><span class="token punctuation">,</span>
    <span class="token constant">DEBUG</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>

<span class="token comment">/**
 * This is equivalent to:
 * type LogLevelStrings = 'ERROR' | 'WARN' | 'INFO' | 'DEBUG';
 */</span>
<span class="token keyword">type</span> <span class="token class-name">LogLevelStrings</span> <span class="token operator">=</span> <span class="token keyword">keyof</span> <span class="token keyword">typeof</span> LogLevel<span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">printImportant</span><span class="token punctuation">(</span>key<span class="token operator">:</span> LogLevelStrings<span class="token punctuation">,</span> message<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> num <span class="token operator">=</span> LogLevel<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>num <span class="token operator">&lt;=</span> LogLevel<span class="token punctuation">.</span><span class="token constant">WARN</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Log level key is:"</span><span class="token punctuation">,</span> key<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Log level value is:"</span><span class="token punctuation">,</span> num<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Log level message is:"</span><span class="token punctuation">,</span> message<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token function">printImportant</span><span class="token punctuation">(</span><span class="token string">"ERROR"</span><span class="token punctuation">,</span> <span class="token string">"This is a message"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h4 id="对象的使用详情">对象的使用详情</h4>
<p>In JavaScript, the fundamental way that we group and pass around data is through objects. In TypeScript, we represent those through <em>object types</em>.</p>
<p>As we’ve seen, they can be anonymous:</p>
<pre class="line-numbers language-none"><code class="language-none">function greet(person: { name: string; age: number }) {
  return "Hello " + person.name;
}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p>or they can be named by using either an interface</p>
<pre class="line-numbers language-none"><code class="language-none">interface Person {
  name: string;
  age: number;
}
 
function greet(person: Person) {
  return "Hello " + person.name;
}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>or a type alias.</p>
<pre class="line-numbers language-none"><code class="language-none">type Person = {
  name: string;
  age: number;
};
 
function greet(person: Person) {
  return "Hello " + person.name;
}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>In all three examples above, we’ve written functions that take objects that contain the property <code>name</code> (which must be a <code>string</code>) and <code>age</code> (which must be a <code>number</code>).</p>
<h4 id="类型别名和接口的区别">类型别名和接口的区别</h4>
<p>类型别名和接口非常相似，在很多情况下你可以在它们之间自由选择。几乎所有接口的功能都可以在类型中使用，关键的区别在于，类型不能被重新打开以添加新的属性，而接口则总是可以扩展的。</p>
<p>You’ll learn more about these concepts in later chapters, so don’t worry if you don’t understand all of these right away.</p>
<ul>
<li>Prior to TypeScript version 4.2, type alias names <a target="_blank" rel="noopener" href="https://www.typescriptlang.org/play?#code/PTAEGEHsFsAcEsA2BTATqNrLusgzngIYDm+oA7koqIYuYQJ56gCueyoAUCKAC4AWHAHaFcoSADMaQ0PCG80EwgGNkALk6c5C1EtWgAsqOi1QAb06groEbjWg8vVHOKcAvpokshy3vEgyyMr8kEbQJogAFND2YREAlOaW1soBeJAoAHSIkMTRmbbI8e6aPMiZxJmgACqCGKhY6ABGyDnkFFQ0dIzMbBwCwqIccabcYLyQoKjIEmh8kwN8DLAc5PzwwbLMyAAeK77IACYaQSEjUWZWhfYAjABMAMwALA+gbsVjoADqgjKESytQPxCHghAByXigYgBfr8LAsYj8aQMUASbDQcRSExCeCwFiIQh+AKfAYyBiQFgOPyIaikSGLQo0Zj-aazaY+dSaXjLDgAGXgAC9CKhDqAALxJaw2Ib2RzOISuDycLw+ImBYKQflCkWRRD2LXCw6JCxS1JCdJZHJ5RAFIbFJU8ADKC3WzEcnVZaGYE1ABpFnFOmsFhsil2uoHuzwArO9SmAAEIsSFrZB-GgAjjA5gtVN8VCEc1o1C4Q4AGlR2AwO1EsBQoAAbvB-gJ4HhPgB5aDwem-Ph1TCV3AEEirTp4ELtRbTPD4vwKjOfAuioSQHuDXBcnmgACC+eCONFEs73YAPGGZVT5cRyyhiHh7AAON7lsG3vBggB8XGV3l8-nVISOgghxoLq9i7io-AHsayRWGaFrlFauq2rg9qaIGQHwCBqChtKdgRo8TxRjeyB3o+7xAA"><em>may</em> appear in error messages</a>, sometimes in place of the equivalent anonymous type (which may or may not be desirable). Interfaces will always be named in error messages.</li>
<li>Type aliases may not participate <a target="_blank" rel="noopener" href="https://www.typescriptlang.org/play?#code/PTAEEEDtQS0gXApgJwGYEMDGjSfdAIx2UQFoB7AB0UkQBMAoEUfO0Wgd1ADd0AbAK6IAzizp16ALgYM4SNFhwBZdAFtV-UAG8GoPaADmNAcMmhh8ZHAMMAvjLkoM2UCvWad+0ARL0A-GYWVpA29gyY5JAWLJAwGnxmbvGgALzauvpGkCZmAEQAjABMAMwALLkANBl6zABi6DB8okR4Jjg+iPSgABboovDk3jjo5pbW1d6+dGb5djLwAJ7UoABKiJTwjThpnpnGpqPBoTLMAJrkArj4kOTwYmycPOhW6AR8IrDQ8N04wmo4HHQCwYi2Waw2W1S6S8HX8gTGITsQA">in declaration merging, but interfaces can</a>.</li>
<li>Interfaces may only be used to <a target="_blank" rel="noopener" href="https://www.typescriptlang.org/play?#code/PTAEAkFMCdIcgM6gC4HcD2pIA8CGBbABwBtIl0AzUAKBFAFcEBLAOwHMUBPQs0XFgCahWyGBVwBjMrTDJMAshOhMARpD4tQ6FQCtIE5DWoixk9QEEWAeV37kARlABvaqDegAbrmL1IALlAEZGV2agBfampkbgtrWwMAJlAAXmdXdy8ff0Dg1jZwyLoAVWZ2Lh5QVHUJflAlSFxROsY5fFAWAmk6CnRoLGwmILzQQmV8JmQmDzI-SOiKgGV+CaYAL0gBBdyy1KCQ-Pn1AFFplgA5enw1PtSWS+vCsAAVAAtB4QQWOEMKBuYVUiVCYvYQsUTQcRSBDGMGmKSgAAa-VEgiQe2GLgKQA">declare the shapes of objects, not rename primitives</a>.</li>
<li>Interface names will <a target="_blank" rel="noopener" href="https://www.typescriptlang.org/play?#code/PTAEGEHsFsAcEsA2BTATqNrLusgzngIYDm+oA7koqIYuYQJ56gCueyoAUCKAC4AWHAHaFcoSADMaQ0PCG80EwgGNkALk6c5C1EtWgAsqOi1QAb06groEbjWg8vVHOKcAvpokshy3vEgyyMr8kEbQJogAFND2YREAlOaW1soBeJAoAHSIkMTRmbbI8e6aPMiZxJmgACqCGKhY6ABGyDnkFFQ0dIzMbBwCwqIccabcYLyQoKjIEmh8kwN8DLAc5PzwwbLMyAAeK77IACYaQSEjUWY2Q-YAjABMAMwALA+gbsVjNXW8yxySoAADaAA0CCaZbPh1XYqXgOIY0ZgmcK0AA0nyaLFhhGY8F4AHJmEJILCWsgZId4NNfIgGFdcIcUTVfgBlZTOWC8T7kAJ42G4eT+GS42QyRaYbCgXAEEguTzeXyCjDBSAAQSE8Ai0Xsl0K9kcziExDeiQs1lAqSE6SyOTy0AKQ2KHk4p1V6s1OuuoHuzwArMagA"><em>always</em> appear in their original form</a> in error messages, but <em>only</em> when they are used by name.</li>
</ul>
<p>For the most part, you can choose based on personal preference, and TypeScript will tell you if it needs something to be the other kind of declaration. If you would like a heuristic, use <code>interface</code> until you need to use features from <code>type</code>.</p>
<h2 id="应用实例">应用实例</h2>
<h3 id="根据不同后端环境切换接口集">根据不同后端环境切换接口集</h3>
<h4 id="应用场景">应用场景</h4>
<ul>
<li>前端使用同样的代码, 接口区分单体/微服务, 故需要根据配置使用不用的接口文档</li>
<li>vue2 升级到 vue3 保证语法规范且尽量少的修改</li>
</ul>
<h4 id="vue2使用样例">vue2使用样例</h4>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 全局参数</span>
<span class="token keyword">const</span> path <span class="token operator">=</span> process<span class="token punctuation">.</span>env<span class="token punctuation">.</span><span class="token constant">VUE_APP_SERVER_TYPE</span>
<span class="token keyword">const</span> system <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'@api/api-'</span> <span class="token operator">+</span> path<span class="token punctuation">)</span>
module<span class="token punctuation">.</span>exports <span class="token operator">=</span> system
<span class="token comment">// import { demoUrl } from '@/api/api'</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h4 id="require-exports和import-export的区别">require/exports和import/export的区别</h4>
<p>require/exports和import/export <a target="_blank" rel="noopener" href="https://blog.csdn.net/xiaoxiaoluckylucky/article/details/118437651">https://blog.csdn.net/xiaoxiaoluckylucky/article/details/118437651</a><br>
require/exports与import/export，有啥不一样的 <a target="_blank" rel="noopener" href="https://blog.51cto.com/u_15089765/2600897">https://blog.51cto.com/u_15089765/2600897</a></p>
<h1>方式1: 定义所有接口, 根据变量动态加载</h1>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token comment">// 需要导出default才能被外部直接用 {使用}</span>
<span class="token comment">// export const defaultApi: PlatformApi = import.meta.env.VITE_GLOB_APP_SERVER_TYPE === 'vue' ? apiVue : apiCloud;</span>
<span class="token keyword">const</span> defaultApi<span class="token operator">:</span> PlatformApi <span class="token operator">=</span>
    <span class="token keyword">import</span><span class="token punctuation">.</span>meta<span class="token punctuation">.</span>env<span class="token punctuation">.</span><span class="token constant">VITE_GLOB_APP_SERVER_TYPE</span> <span class="token operator">===</span> <span class="token string">'vue'</span> <span class="token operator">?</span> apiVue <span class="token operator">:</span> apiCloud<span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> defaultApi<span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token keyword">interface</span> <span class="token class-name">PlatformApi</span> <span class="token punctuation">{</span>
    demoUrl<span class="token operator">?</span><span class="token operator">:</span> <span class="token builtin">string</span>
<span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token comment">// ROORO: No matching export in "src/api/api.ts" for import "demoUrl"</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span>demoUrl<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'/@/api/api'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> defaultApi <span class="token keyword">from</span> <span class="token string">'/@/api/api'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> <span class="token punctuation">{</span>demoUrl<span class="token punctuation">}</span> <span class="token operator">=</span> defaultApi
<span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>defaultApi<span class="token punctuation">.</span>demoUrl<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<ul>
<li>使用时需要通过<code>defaultApi</code>对象二次导入</li>
</ul>
<h1>方式2 替换构建路径</h1>
<p>vite.config.ts</p>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token punctuation">{</span>command<span class="token punctuation">,</span> mode<span class="token punctuation">}</span><span class="token operator">:</span> ConfigEnv<span class="token punctuation">)</span><span class="token operator">:</span> UserConfig <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> <span class="token punctuation">{</span><span class="token constant">VITE_GLOB_APP_SERVER_TYPE</span><span class="token punctuation">}</span> <span class="token operator">=</span> viteEnv<span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
        resolve<span class="token operator">:</span> <span class="token punctuation">{</span>
            alias<span class="token operator">:</span> <span class="token punctuation">[</span>
                <span class="token punctuation">{</span>
                    <span class="token comment">// '/@/api/api' 该路径过于常用, 会覆盖别的匹配模式</span>
                    find<span class="token operator">:</span> <span class="token string">'/@/api/api-zh'</span><span class="token punctuation">,</span>
                    replacement<span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">pathResolve</span><span class="token punctuation">(</span><span class="token string">'src'</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/api/api-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token constant">VITE_GLOB_APP_SERVER_TYPE</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span>
                <span class="token punctuation">}</span><span class="token punctuation">,</span>
            <span class="token punctuation">]</span><span class="token punctuation">,</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">import</span> <span class="token punctuation">{</span>demoUrl<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'api-zh'</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<ul>
<li>方法名有写错的风险</li>
</ul>
<h1>方式3 moduleSuffixes</h1>
<p>moduleSuffixes <a target="_blank" rel="noopener" href="https://www.typescriptlang.org/tsconfig#moduleSuffixes">https://www.typescriptlang.org/tsconfig#moduleSuffixes</a></p>
<p>tsconfig.json</p>
<pre class="line-numbers language-json" data-language="json"><code class="language-json"><span class="token punctuation">{</span>
  <span class="token property">"compilerOptions"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">"moduleSuffixes"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
      <span class="token string">".service-vue"</span><span class="token punctuation">,</span>
      <span class="token string">".service-cloud"</span><span class="token punctuation">,</span>
      <span class="token string">""</span>
    <span class="token punctuation">]</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<ul>
<li>原来的文件改名为 api.service-vue&amp;api.service-cloud</li>
<li>引用正常引用即可 <code>官方提示需要 import * as Api from '/@/api/api';</code></li>
</ul>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">{</span>demoUrl<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'/@/api/api'</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<ul>
<li>版本 typescript 4.7.0+ &amp; node16+ ; 舍弃</li>
</ul>

                
            </div>
            <hr/>

            

    <div class="reprint" id="reprint-statement">
        
            <div class="reprint__author">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-user">
                        文章作者:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="/about" rel="external nofollow noreferrer">艾茜茜</a>
                </span>
            </div>
            <div class="reprint__type">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-link">
                        文章链接:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="http://wangjueya.github.io/typescript/">http://wangjueya.github.io/typescript/</a>
                </span>
            </div>
            <div class="reprint__notice">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-copyright">
                        版权声明:
                    </i>
                </span>
                <span class="reprint-info">
                    本博客所有文章除特別声明外，均采用
                    <a href="https://creativecommons.org/licenses/by/4.0/deed.zh" rel="external nofollow noreferrer" target="_blank">CC BY 4.0</a>
                    许可协议。转载请注明来源
                    <a href="/about" target="_blank">艾茜茜</a>
                    !
                </span>
            </div>
        
    </div>

    <script async defer>
      document.addEventListener("copy", function (e) {
        let toastHTML = '<span>复制成功，请遵循本文的转载规则</span><button class="btn-flat toast-action" onclick="navToReprintStatement()" style="font-size: smaller">查看</a>';
        M.toast({html: toastHTML})
      });

      function navToReprintStatement() {
        $("html, body").animate({scrollTop: $("#reprint-statement").offset().top - 80}, 800);
      }
    </script>



            <div class="tag_share" style="display: block;">
                <div class="post-meta__tag-list" style="display: inline-block;">
                    
                        <div class="article-tag">
                            
                                <a href="/tags/TypeScript/">
                                    <span class="chip bg-color">TypeScript</span>
                                </a>
                            
                        </div>
                    
                </div>
                <div class="post_share" style="zoom: 80%; width: fit-content; display: inline-block; float: right; margin: -0.15rem 0;">
                    <link rel="stylesheet" type="text/css" href="/libs/share/css/share.min.css">
<div id="article-share">

    
    <div class="social-share" data-sites="twitter,facebook,google,qq,qzone,wechat,weibo,douban,linkedin" data-wechat-qrcode-helper="<p>微信扫一扫即可分享！</p>"></div>
    <script src="/libs/share/js/social-share.min.js"></script>
    

    

</div>

                </div>
            </div>
            
                <div id="reward">
    <a href="#rewardModal" class="reward-link modal-trigger btn-floating btn-medium waves-effect waves-light red">赏</a>

    <!-- Modal Structure -->
    <div id="rewardModal" class="modal">
        <div class="modal-content">
            <a class="close modal-close"><i class="fas fa-times"></i></a>
            <h4 class="reward-title">你的赏识是我前进的动力</h4>
            <div class="reward-content">
                <div class="reward-tabs">
                    <ul class="tabs row">
                        <li class="tab col s6 alipay-tab waves-effect waves-light"><a href="#alipay">支付宝</a></li>
                        <li class="tab col s6 wechat-tab waves-effect waves-light"><a href="#wechat">微 信</a></li>
                    </ul>
                    <div id="alipay">
                        <img src="/medias/reward/alipay.png" class="reward-img" alt="支付宝打赏二维码">
                    </div>
                    <div id="wechat">
                        <img src="/medias/reward/wechat.png" class="reward-img" alt="微信打赏二维码">
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
    $(function () {
        $('.tabs').tabs();
    });
</script>

            
        </div>
    </div>

    

    

    

    

    

    

    

    

    

<article id="prenext-posts" class="prev-next articles">
    <div class="row article-row">
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge left-badge text-color">
                <i class="fas fa-chevron-left"></i>&nbsp;上一篇</div>
            <div class="card">
                <a href="/aop/">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/14.jpg" class="responsive-img" alt="AOP理论与实战">
                        
                        <span class="card-title">AOP理论与实战</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            AOP理论与实战
                        
                    </div>
                    <div class="publish-info">
                        <span class="publish-date">
                            <i class="far fa-clock fa-fw icon-date"></i>2022-10-19
                        </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/06-Frameworks-and-Components/" class="post-category">
                                    06-Frameworks-and-Components
                                </a>
                            
                            <a href="/categories/06-Frameworks-and-Components/Spring/" class="post-category">
                                    Spring
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/spring/">
                        <span class="chip bg-color">spring</span>
                    </a>
                    
                    <a href="/tags/AOP/">
                        <span class="chip bg-color">AOP</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge right-badge text-color">
                下一篇&nbsp;<i class="fas fa-chevron-right"></i>
            </div>
            <div class="card">
                <a href="/spark/">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/21.jpg" class="responsive-img" alt="Spark">
                        
                        <span class="card-title">Spark</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            Spark
                        
                    </div>
                    <div class="publish-info">
                            <span class="publish-date">
                                <i class="far fa-clock fa-fw icon-date"></i>2022-10-16
                            </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/06-Frameworks-and-Components/" class="post-category">
                                    06-Frameworks-and-Components
                                </a>
                            
                            <a href="/categories/06-Frameworks-and-Components/Big-Data/" class="post-category">
                                    Big-Data
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/Spark/">
                        <span class="chip bg-color">Spark</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
    </div>
</article>

</div>



<!-- 代码块功能依赖 -->
<script type="text/javascript" src="/libs/codeBlock/codeBlockFuction.js"></script>


  <!-- 是否加载使用自带的 prismjs. -->
  <script type="text/javascript" src="/libs/prism/prism.min.js"></script>


<!-- 代码语言 -->

<script type="text/javascript" src="/libs/codeBlock/codeLang.js"></script>


<!-- 代码块复制 -->

<script type="text/javascript" src="/libs/codeBlock/codeCopy.js"></script>


<!-- 代码块收缩 -->

<script type="text/javascript" src="/libs/codeBlock/codeShrink.js"></script>



    </div>
    <div id="toc-aside" class="expanded col l3 hide-on-med-and-down">
        <div class="toc-widget card" style="background-color: white;">
            <div class="toc-title"><i class="far fa-list-alt"></i>&nbsp;&nbsp;目录</div>
            <div id="toc-content"></div>
        </div>
    </div>
</div>

<!-- TOC 悬浮按钮. -->

<div id="floating-toc-btn" class="hide-on-med-and-down">
    <a class="btn-floating btn-large bg-color">
        <i class="fas fa-list-ul"></i>
    </a>
</div>


<script src="/libs/tocbot/tocbot.min.js"></script>
<script>
    $(function () {
        tocbot.init({
            tocSelector: '#toc-content',
            contentSelector: '#articleContent',
            headingsOffset: -($(window).height() * 0.4 - 45),
            collapseDepth: Number('0'),
            headingSelector: 'h2, h3, h4'
        });

        // Set scroll toc fixed.
        let tocHeight = parseInt($(window).height() * 0.4 - 64);
        let $tocWidget = $('.toc-widget');
        $(window).scroll(function () {
            let scroll = $(window).scrollTop();
            /* add post toc fixed. */
            if (scroll > tocHeight) {
                $tocWidget.addClass('toc-fixed');
            } else {
                $tocWidget.removeClass('toc-fixed');
            }
        });

        
        /* 修复文章卡片 div 的宽度. */
        let fixPostCardWidth = function (srcId, targetId) {
            let srcDiv = $('#' + srcId);
            if (srcDiv.length === 0) {
                return;
            }

            let w = srcDiv.width();
            if (w >= 450) {
                w = w + 21;
            } else if (w >= 350 && w < 450) {
                w = w + 18;
            } else if (w >= 300 && w < 350) {
                w = w + 16;
            } else {
                w = w + 14;
            }
            $('#' + targetId).width(w);
        };

        // 切换TOC目录展开收缩的相关操作.
        const expandedClass = 'expanded';
        let $tocAside = $('#toc-aside');
        let $mainContent = $('#main-content');
        $('#floating-toc-btn .btn-floating').click(function () {
            if ($tocAside.hasClass(expandedClass)) {
                $tocAside.removeClass(expandedClass).hide();
                $mainContent.removeClass('l9');
            } else {
                $tocAside.addClass(expandedClass).show();
                $mainContent.addClass('l9');
            }
            fixPostCardWidth('artDetail', 'prenext-posts');
        });
        
    });
</script>

    

</main>




    <footer class="page-footer bg-color">
    
        <link rel="stylesheet" href="/libs/aplayer/APlayer.min.css">
<style>
    .aplayer .aplayer-lrc p {
        
        display: none;
        
        font-size: 12px;
        font-weight: 700;
        line-height: 16px !important;
    }

    .aplayer .aplayer-lrc p.aplayer-lrc-current {
        
        display: none;
        
        font-size: 15px;
        color: #42b983;
    }

    
    .aplayer.aplayer-fixed.aplayer-narrow .aplayer-body {
        left: -66px !important;
    }

    .aplayer.aplayer-fixed.aplayer-narrow .aplayer-body:hover {
        left: 0px !important;
    }

    
</style>
<div class="">
    
    <div class="row">
        <meting-js class="col l8 offset-l2 m10 offset-m1 s12"
                   server="netease"
                   type="playlist"
                   id="503838841"
                   fixed='true'
                   autoplay='false'
                   theme='#42b983'
                   loop='all'
                   order='random'
                   preload='auto'
                   volume='0.7'
                   list-folded='true'
        >
        </meting-js>
    </div>
</div>

<script src="/libs/aplayer/APlayer.min.js"></script>
<script src="/libs/aplayer/Meting.min.js"></script>

    

    <div class="container row center-align"
         style="margin-bottom: 0px !important;">
        <div class="col s12 m8 l8 copy-right">
            Copyright&nbsp;&copy;
            
                <span id="year">2019-2025</span>
            
            <a href="/about" target="_blank">艾茜茜</a>
            |&nbsp;Powered by&nbsp;<a href="https://hexo.io/" target="_blank">Hexo</a>
            |&nbsp;Theme&nbsp;<a href="https://github.com/WANGJUEYA/hexo-theme-christmas-tree.git" target="_blank">christmas-tree</a>
            <br>
            
                &nbsp;<i class="fas fa-chart-area"></i>&nbsp;站点总字数:&nbsp;<span
                        class="white-color">67.8k</span>
            
            
            
                
            
            
                <span id="busuanzi_container_site_pv">
                &nbsp;|&nbsp;<i class="far fa-eye"></i>&nbsp;总访问量:&nbsp;
                    <span id="busuanzi_value_site_pv" class="white-color"></span>
            </span>
            
            
                <span id="busuanzi_container_site_uv">
                &nbsp;|&nbsp;<i class="fas fa-users"></i>&nbsp;总访问人数:&nbsp;
                    <span id="busuanzi_value_site_uv" class="white-color"></span>
            </span>
            
            <br>

            <!-- 运行天数提醒. -->
            
            <br>
            
        </div>
        <div class="col s12 m4 l4 social-link social-statis">
    <a href="https://github.com/wangjueya" class="tooltipped" target="_blank" data-tooltip="访问我的GitHub" data-position="top" data-delay="50">
        <i class="fab fa-github"></i>
    </a>



    <a href="mailto:573711282@qq.com" class="tooltipped" target="_blank" data-tooltip="邮件联系我" data-position="top" data-delay="50">
        <i class="fas fa-envelope-open"></i>
    </a>







    <a href="tencent://AddContact/?fromId=50&fromSubId=1&subcmd=all&uin=573711282" class="tooltipped" target="_blank" data-tooltip="QQ联系我: 573711282" data-position="top" data-delay="50">
        <i class="fab fa-qq"></i>
    </a>







    <a href="/atom.xml" class="tooltipped" target="_blank" data-tooltip="RSS 订阅" data-position="top" data-delay="50">
        <i class="fas fa-rss"></i>
    </a>

</div>
    </div>
</footer>

<div class="progress-bar"></div>


    <!-- 搜索遮罩框 -->
<div id="searchModal" class="modal">
    <div class="modal-content">
        <div class="search-header">
            <span class="title"><i class="fas fa-search"></i>&nbsp;&nbsp;搜索</span>
            <input type="search" id="searchInput" name="s" placeholder="请输入搜索的关键字"
                   class="search-input">
        </div>
        <div id="searchResult"></div>
    </div>
</div>

<script type="text/javascript">
$(function () {
    var searchFunc = function (path, search_id, content_id) {
        'use strict';
        $.ajax({
            url: path,
            dataType: "xml",
            success: function (xmlResponse) {
                // get the contents from search data
                var datas = $("entry", xmlResponse).map(function () {
                    return {
                        title: $("title", this).text(),
                        content: $("content", this).text(),
                        url: $("url", this).text()
                    };
                }).get();
                var $input = document.getElementById(search_id);
                var $resultContent = document.getElementById(content_id);
                $input.addEventListener('input', function () {
                    var str = '<ul class=\"search-result-list\">';
                    var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
                    $resultContent.innerHTML = "";
                    if (this.value.trim().length <= 0) {
                        return;
                    }
                    // perform local searching
                    datas.forEach(function (data) {
                        var isMatch = true;
                        var data_title = data.title.trim().toLowerCase();
                        var data_content = data.content.trim().replace(/<[^>]+>/g, "").toLowerCase();
                        var data_url = data.url;
                        data_url = data_url.indexOf('/') === 0 ? data.url : '/' + data_url;
                        var index_title = -1;
                        var index_content = -1;
                        var first_occur = -1;
                        // only match artiles with not empty titles and contents
                        if (data_title !== '' && data_content !== '') {
                            keywords.forEach(function (keyword, i) {
                                index_title = data_title.indexOf(keyword);
                                index_content = data_content.indexOf(keyword);
                                if (index_title < 0 && index_content < 0) {
                                    isMatch = false;
                                } else {
                                    if (index_content < 0) {
                                        index_content = 0;
                                    }
                                    if (i === 0) {
                                        first_occur = index_content;
                                    }
                                }
                            });
                        }
                        // show search results
                        if (isMatch) {
                            str += "<li><a href='" + data_url + "' class='search-result-title'>" + data_title + "</a>";
                            var content = data.content.trim().replace(/<[^>]+>/g, "");
                            if (first_occur >= 0) {
                                // cut out 100 characters
                                var start = first_occur - 20;
                                var end = first_occur + 80;
                                if (start < 0) {
                                    start = 0;
                                }
                                if (start === 0) {
                                    end = 100;
                                }
                                if (end > content.length) {
                                    end = content.length;
                                }
                                var match_content = content.substr(start, end);
                                // highlight all keywords
                                keywords.forEach(function (keyword) {
                                    var regS = new RegExp(keyword, "gi");
                                    match_content = match_content.replace(regS, "<em class=\"search-keyword\">" + keyword + "</em>");
                                });

                                str += "<p class=\"search-result\">" + match_content + "...</p>"
                            }
                            str += "</li>";
                        }
                    });
                    str += "</ul>";
                    $resultContent.innerHTML = str;
                });
            }
        });
    };

    searchFunc('/search.xml', 'searchInput', 'searchResult');
});
</script>

    <!-- 白天和黑夜主题 -->
<div class="stars-con">
    <div id="stars"></div>
    <div id="stars2"></div>
    <div id="stars3"></div>  
</div>

<script>
    function switchNightMode() {
        $('<div class="Cuteen_DarkSky"><div class="Cuteen_DarkPlanet"></div></div>').appendTo($('body')),
        setTimeout(function () {
            $('body').hasClass('DarkMode') 
            ? ($('body').removeClass('DarkMode'), localStorage.setItem('isDark', '0'), $('#sum-moon-icon').removeClass("fa-sun").addClass('fa-moon')) 
            : ($('body').addClass('DarkMode'), localStorage.setItem('isDark', '1'), $('#sum-moon-icon').addClass("fa-sun").removeClass('fa-moon')),
            
            setTimeout(function () {
            $('.Cuteen_DarkSky').fadeOut(1e3, function () {
                $(this).remove()
            })
            }, 2e3)
        })
    }
</script>

    <!-- 回到顶部按钮 -->
<div id="backTop" class="top-scroll">
    <a class="btn-floating btn-large waves-effect waves-light" href="#!">
        <i class="fas fa-arrow-up"></i>
    </a>
</div>


    <script src="/libs/materialize/materialize.min.js"></script>
    <script src="/libs/masonry/masonry.pkgd.min.js"></script>
    <script src="/libs/aos/aos.js"></script>
    <script src="/libs/scrollprogress/scrollProgress.min.js"></script>
    <script src="/libs/lightGallery/js/lightgallery-all.min.js"></script>
    <script src="/js/matery.js"></script>

    
        <!-- <script src='https://unpkg.com/mermaid@latest/dist/mermaid.min.js'></script> -->
        <script src='/libs/mermaid/mermaid.min.js'></script>
        <script>
          if (window.mermaid) {
            mermaid.initialize({theme: 'forest'});
          }
        </script>
    

    

    <!-- 雪花特效 -->
    

    <!-- 鼠标星星特效 -->
    

     
        <script src="https://ssl.captcha.qq.com/TCaptcha.js"></script>
        <script src="/libs/others/TencentCaptcha.js"></script>
        <button id="TencentCaptcha" data-appid="xxxxxxxxxx" data-cbfn="callback" type="button" hidden></button>
    

    <!-- Baidu Analytics -->

    <!-- Baidu Push -->

<script>
    (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
            bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        } else {
            bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
    })();
</script>

    
    <script src="/libs/others/clicklove.js" async="async"></script>
    
    
    <script async src="/libs/others/busuanzi.pure.mini.js"></script>
    

    

    

    <!--腾讯兔小巢-->
    
    

    

    

    
    <script src="/libs/instantpage/instantpage.js" type="module"></script>
    

</body>

</html>
